Skip to content

[ENH] Add a tool to reason through the state space of bootstrap. #4558

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 19, 2025

Conversation

rescrv
Copy link
Contributor

@rescrv rescrv commented May 15, 2025

Description of changes

The space of cases I have to handle:

panic(BenignRace, AlreadyInitialized, Uninitialized) -> cannot double-initialize manifest
panic(BenignRace, AlreadyInitialized, Failure) -> cannot double-initialize manifest
panic(BenignRace, AlreadyInitialized, Success) -> cannot double-initialize manifest
panic(Success, AlreadyInitialized, Uninitialized) -> cannot double-initialize manifest
panic(Success, AlreadyInitialized, Failure) -> cannot double-initialize manifest
panic(Success, AlreadyInitialized, Success) -> cannot double-initialize manifest

panic(BenignRace, Uninitialized, Failure) -> failed to install recovered manifest
panic(BenignRace, Success, Failure) -> failed to install recovered manifest
panic(Success, Uninitialized, Failure) -> failed to install recovered manifest
panic(Success, Success, Failure) -> failed to install recovered manifest

panic(BenignRace, Uninitialized, Uninitialized) -> cannot have manifest become uninitialized
panic(BenignRace, Success, Uninitialized) -> cannot have manifest become uninitialized
panic(Success, Uninitialized, Uninitialized) -> cannot have manifest become uninitialized
panic(Success, Success, Uninitialized) -> cannot have manifest become uninitialized

Committing so I don't lose it.

Test plan

This is a planning tool. It doesn't need testing as it's part of a testing effort.

Documentation Changes

No docs here.

Copy link

Reviewer Checklist

Please leverage this checklist to ensure your code review is thorough before approving

Testing, Bugs, Errors, Logs, Documentation

  • Can you think of any use case in which the code does not behave as intended? Have they been tested?
  • Can you think of any inputs or external events that could break the code? Is user input validated and safe? Have they been tested?
  • If appropriate, are there adequate property based tests?
  • If appropriate, are there adequate unit tests?
  • Should any logging, debugging, tracing information be added or removed?
  • Are error messages user-friendly?
  • Have all documentation changes needed been made?
  • Have all non-obvious changes been commented?

System Compatibility

  • Are there any potential impacts on other parts of the system or backward compatibility?
  • Does this change intersect with any items on our roadmap, and if so, is there a plan for fitting them together?

Quality

  • Is this code of a unexpectedly high quality (Readability, Modularity, Intuitiveness)

Copy link
Contributor

propel-code-bot bot commented May 15, 2025

Add standalone Rust example to exhaustively reason about WAL bootstrap states

Adds rust/wal3/examples/wal3-bootstrap-reasoner.rs, an exploratory CLI that enumerates all combinations of fragment, initialize-manifest, and recover-manifest states (3×3×3 = 27) and classifies each through a set of rule functions. The tool prints panic, raise, or silently drops / accepts states, helping developers validate bootstrap invariants without affecting production code.

Key Changes:
• New enums: FragmentState, InitializeManifest, RecoverManifest (+ helpers to iterate)
• Disposition enum encodes Good/Pass/Drop/Panic/Raise outcomes
• Four rule functions: happy_paths, error_paths, conflict_on_fragment, unconditionally_raise
main() builds full state space, applies rules in order, prints results for Panic/Raise cases

Affected Areas:
• rust/wal3/examples/wal3-bootstrap-reasoner.rs (new example tool only)

This summary was automatically generated by @propel-code-bot

Comment on lines +9 to +14
#[derive(Clone, Copy, Debug)]
enum FragmentState {
BenignRace,
Conflict,
Success,
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[BestPractice]

Consider adding #[derive(PartialEq, Eq)] to all enum types since they're being compared with matches!. This improves code readability and future-proofs the enums if you need to use equality checks elsewhere.

}
}

enum Disposition {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[BestPractice]

The Disposition enum would benefit from adding #[derive(Debug)] to improve debugging if needed. Since it contains other Debug-derived types, this would be straightforward.

@rescrv rescrv requested a review from Copilot May 15, 2025 22:44
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Adds a new example tool that exhaustively explores all combinations of fragment, initialization, and recovery states during bootstrap, classifying each as good, dropped, panicked, or raised.

  • Introduces three enums (FragmentState, InitializeManifest, RecoverManifest) and a Disposition enum
  • Implements rules (happy_paths, conflict_on_fragment, error_paths, unconditionally_raise) to categorize each state triple
  • Adds a main that iterates through all states and applies rules, printing panics and raises
Comments suppressed due to low confidence (1)

rust/wal3/examples/wal3-bootstrap-reasoner.rs:102

  • [nitpick] Function error_paths emits panic dispositions; consider renaming it to panic_paths or similar to more accurately reflect its behavior.
fn error_paths(fs: FragmentState, im: InitializeManifest, rm: RecoverManifest) -> Disposition {

Comment on lines 165 to 176
println!("panic({fs:?}, {im:?}, {rm:?}) -> {reason}");
break;
}
Disposition::Drop(_, _, _, _) => {
break;
}
Disposition::Raise(reason, fs, im, rm) => {
println!("raise({fs:?}, {im:?}, {rm:?}) -> {reason}");
Copy link
Preview

Copilot AI May 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Invalid use of named formatting placeholders without supplying the corresponding arguments. Consider using positional placeholders with arguments, e.g. println!("panic({:?}, {:?}, {:?}) -> {}", fs, im, rm, reason);.

Suggested change
println!("panic({fs:?}, {im:?}, {rm:?}) -> {reason}");
break;
}
Disposition::Drop(_, _, _, _) => {
break;
}
Disposition::Raise(reason, fs, im, rm) => {
println!("raise({fs:?}, {im:?}, {rm:?}) -> {reason}");
println!("panic({:?}, {:?}, {:?}) -> {}", fs, im, rm, reason);
break;
}
Disposition::Drop(_, _, _, _) => {
break;
}
Disposition::Raise(reason, fs, im, rm) => {
println!("raise({:?}, {:?}, {:?}) -> {}", fs, im, rm, reason);

Copilot uses AI. Check for mistakes.

break;
}
Disposition::Raise(reason, fs, im, rm) => {
println!("raise({fs:?}, {im:?}, {rm:?}) -> {reason}");
Copy link
Preview

Copilot AI May 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Invalid use of named formatting placeholders without supplying the corresponding arguments. Consider using positional placeholders with arguments, e.g. println!("raise({:?}, {:?}, {:?}) -> {}", fs, im, rm, reason);.

Suggested change
println!("raise({fs:?}, {im:?}, {rm:?}) -> {reason}");
println!("raise({:?}, {:?}, {:?}) -> {}", fs, im, rm, reason);

Copilot uses AI. Check for mistakes.

Base automatically changed from rescrv/sealing-log-service to main May 16, 2025 19:35
@rescrv rescrv requested review from codetheweb and sanketkedia May 19, 2025 16:06
rescrv added 2 commits May 19, 2025 09:41
The space of cases I have to handle:

panic(BenignRace, AlreadyInitialized, Uninitialized) -> cannot double-initialize manifest
panic(BenignRace, AlreadyInitialized, Failure) -> cannot double-initialize manifest
panic(BenignRace, AlreadyInitialized, Success) -> cannot double-initialize manifest
panic(Success, AlreadyInitialized, Uninitialized) -> cannot double-initialize manifest
panic(Success, AlreadyInitialized, Failure) -> cannot double-initialize manifest
panic(Success, AlreadyInitialized, Success) -> cannot double-initialize manifest

panic(BenignRace, Uninitialized, Failure) -> failed to install recovered manifest
panic(BenignRace, Success, Failure) -> failed to install recovered manifest
panic(Success, Uninitialized, Failure) -> failed to install recovered manifest
panic(Success, Success, Failure) -> failed to install recovered manifest

panic(BenignRace, Uninitialized, Uninitialized) -> cannot have manifest become uninitialized
panic(BenignRace, Success, Uninitialized) -> cannot have manifest become uninitialized
panic(Success, Uninitialized, Uninitialized) -> cannot have manifest become uninitialized
panic(Success, Success, Uninitialized) -> cannot have manifest become uninitialized

Committing so I don't lose it.
@rescrv rescrv force-pushed the rescrv/wal3-bootstrap branch from cd14dcb to 307051a Compare May 19, 2025 16:42
@rescrv rescrv merged commit f6271c1 into main May 19, 2025
70 checks passed
@rescrv rescrv deleted the rescrv/wal3-bootstrap branch May 19, 2025 22:06
rescrv added a commit that referenced this pull request May 19, 2025
## Description of changes

This adds a "bootstrap" call to wal3 that copies the data
semi-atomically. It is reasoned to be
safe to do concurrent with all other log operations, but may leave a
FragmentSeqNo(1) lying around
in the event that a log is initialized at the same time it's
bootstrapping. This should never
happen in our system so thankfully we can just leave the hole.

See #4558 for the reasoning.

## Test plan

- [ ] Tests pass locally with `pytest` for python, `yarn test` for js,
`cargo test` for rust

## Documentation Changes

N/A
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants